package com.bysc.cmsservice.handler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bysc.baseservice.config.RabbitmqConfig;
import com.bysc.cmsservice.entity.StudyData;
import com.bysc.cmsservice.service.CmsActivityService;
import com.bysc.cmsservice.service.StudyDataService;
import com.bysc.commonutils.constant.RedisConstant;
import com.bysc.commonutils.enums.ActivityEnum;
import com.bysc.commonutils.enums.CommentEnum;
import com.bysc.commonutils.utils.DateUtil;
import com.bysc.commonutils.utils.ScoreUtil;
import com.bysc.commonutils.vo.CmsActivity;
import com.bysc.commonutils.vo.PostStatsVo;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import static com.bysc.commonutils.constant.RedisConstant.*;


@Component
public class ReceiveHandler {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private CmsActivityService activityService;
    @Autowired
    private StudyDataService studyDataService;

    //监听队列
    @RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_ACTIVITY_INIT})
    public void receive_init(Message message, Channel channel) {
        try {
            //查询所有当日活动
            QueryWrapper<CmsActivity> wrapper = new QueryWrapper<>();
            wrapper.eq("DATE_FORMAT(join_start,'%Y-%m-%d')", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
            wrapper.eq("status", ActivityEnum.JOIN_START.getId());
            List<CmsActivity> list = activityService.list(wrapper);
            for (CmsActivity cmsActivity : list) {
                if (cmsActivity != null) {
                    String id = cmsActivity.getId();
                    Integer aLimit = cmsActivity.getALimit();
                    if (aLimit != null && aLimit > 0 && !redisTemplate.hasKey(RedisConstant.ACTIVITY_NUMBER + id)) { // 初始化过的不再初始化
                        for (int i = 0; i < aLimit; i++) { //初始化名额
                            redisTemplate.opsForList().leftPush(RedisConstant.ACTIVITY_NUMBER + id, id);
                        }
                        //发送消息
                        System.out.println("发布订阅信息："+id);
                        redisTemplate.convertAndSend("activity", id + ":1");
                    }
                }
            }

            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        }


    }


    /**
     * 学习资料分数消费端
     * 监听学习资料分数计算消息
     */
    @RabbitListener(queues = {RabbitmqConfig.QUEUE_STUDY_SCORE})
    public void consumeStudyScoreMessage(Message message, Channel channel) {
        try {
            // 1. 获取学习资料的数据
            QueryWrapper<StudyData> wrapper = new QueryWrapper<>();
            wrapper.select("id", "gmt_create");
            List<StudyData> list = studyDataService.list(wrapper);
            // 2. 计算学习资料热度分数
            HashSet<ZSetOperations.TypedTuple> set = new HashSet<>();
            for (StudyData studyData : list) {
                String id = studyData.getId();
                Date gmtCreate = studyData.getGmtCreate();
                PostStatsVo postStatsVo = new PostStatsVo();
                //取redis中点赞收藏浏览量
                String key = STUDY_DATA + id;
                if (!redisTemplate.hasKey(key)) {
                    continue;
                }
                int like = (int) redisTemplate.opsForHash().get(key, _LIKE);
                int collect = (int) redisTemplate.opsForHash().get(key, _COLLECT);
                int view = (int) redisTemplate.opsForHash().get(key, _VIEW);
                postStatsVo.setLikes(like);
                postStatsVo.setCollects(collect);
                postStatsVo.setViews(view);
                //没有用户信息
                postStatsVo.setActiveUser(false);
                postStatsVo.setAssociationMember(false);
                double heatScore = ScoreUtil.calculateHeatScore(postStatsVo, gmtCreate, CommentEnum.STUDYMATERIAL);
                //将id, heatScore存入set
                set.add(new DefaultTypedTuple(id, heatScore));
                System.out.println("学习资料：" + id + "，热度分数：" + heatScore);
                // 将计算出的热度分数存入 Redis 的 ZSet（有序集合）
                if (set.size() % 10 == 0) {
                    redisTemplate.opsForZSet().add("study_score", set);
                    set.clear();
                }
            }
            redisTemplate.opsForZSet().add("study_score", set);
            System.out.println("学习资料分数计算完成！");
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    @RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_ACTIVITY_END})
    public void receive_end(Message message, Channel channel) {
        try {
            //查询所有当日活动
            QueryWrapper<CmsActivity> wrapper = new QueryWrapper<>();
            wrapper.eq("DATE_FORMAT(join_end,'%Y-%m-%d')", DateUtil.formatDate(new Date(), "yyyy-MM-dd"));
            List<CmsActivity> list = activityService.list(wrapper);
            for (CmsActivity cmsActivity : list) {
                if (cmsActivity != null) {
                    String id = cmsActivity.getId();
                    //清空今日活动数据
                    redisTemplate.delete(RedisConstant.ACTIVITY_NUMBER + id);
                    redisTemplate.delete("activity:join:" + id);
                    redisTemplate.delete("activity:queue:" + id);
                    redisTemplate.delete("activity:submit:" + id);
                    //发送消息
                    redisTemplate.convertAndSend("activity", id + ":-1");
                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                ex.printStackTrace();
            }

        }
    }
}
